﻿#region Copyright information
// 
// Copyright © 2005-2013 Yongkee Cho. All rights reserved.
// 
// This code is a part of the Biological Object Library and governed under the terms of the
// GNU Lesser General  Public License (LGPL) version 2.1 which accompanies this distribution.
// For more information on the LGPL, please visit http://bol.codeplex.com/license.
// 
// - Filename: GraphBase.cs
// - Author: Yongkee Cho
// - Email: yongkeecho@gmail.com
// - Date Created: 2013-01-24 4:34 PM
// - Last Modified: 2013-01-25 3:59 PM
// 
#endregion
using System;
using System.Linq;
using BOL.Linq.Matrix;

namespace BOL.Algorithms.Graph
{
    /// <summary>
    /// Represent an abstract graph class.
    /// </summary>
    public abstract class GraphBase : IGraph, ICloneable
    {
        #region Public properties

        /// <summary>Indicates if this graph is directed or not.</summary>
        public bool IsDirected { get; private set; }

        /// <summary>Returns the number of vertices in the graph.</summary>
        public abstract int Order { get; }

        /// <summary>Returns the number of edges in the graph.</summary>
        public abstract int Size { get; }

        /// <summary>Returns the maximum multiplicity of edges in the graph.</summary>
        public abstract int Multiplicity { get; }

        public bool IsNull { get { return Order + Size == 0; } }

        public bool IsSimple { get { return Multiplicity < 2; } }

        #endregion

        #region Constructors

        protected GraphBase(bool isDirected = true)
        {
            IsDirected = isDirected;
        }

        #endregion

        #region Public methods

        public abstract int[][] DegreeMatrix();

        public abstract bool[][] AdjacencyMatrix();

        public abstract int[][] IncidenceMatrix();

        public int[][] LaplacianMatrix()
        {
            return DegreeMatrix().Subtract(AdjacencyMatrix().Select(x => x.Select(y => y ? 1 : 0).ToArray()).ToArray());
        }

        public abstract int[][] DistanceMatrix();

        #endregion

        #region ICloneable implementation

        /// <summary>
        /// Creates an exact copy of current graph. 
        /// </summary>
        protected abstract IGraph Clone();

        /// <summary>
        /// Creates an exact copy of current graph as an object. 
        /// </summary>
        object ICloneable.Clone()
        {
            return Clone();
        }

        #endregion

        #region Object overriden

        public override string ToString()
        {
            return String.Format("Graph ({0}, #V = {1}, #E = {2})", IsDirected ? "Directed" : "Undirected", Order, Size);
        }

        #endregion
    }
}
